﻿using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Logging;

namespace WT.OpenIddict.Domain.Services.Exceptions;

public class UnifiedExceptionMiddleware
{
    private readonly ILogger<UnifiedExceptionMiddleware> _logger;
    private readonly RequestDelegate _next;

    public UnifiedExceptionMiddleware(
        RequestDelegate next,
        ILogger<UnifiedExceptionMiddleware> logger)
    {
        _next = next;
        _logger = logger;
    }

    public async Task InvokeAsync(HttpContext context)
    {
        try
        {
            await _next(context);
        }
        catch (UnifiedException ex)
        {
            await HandleUnifiedExceptionAsync(context, ex);
        }
        catch (Exception ex)
        {
            await HandleUnexpectedExceptionAsync(context, ex);
        }
    }

    private Task HandleUnifiedExceptionAsync(HttpContext context, UnifiedException exception)
    {
        _logger.LogWarning(exception, "业务异常: {Message}", exception.Message);

        context.Response.StatusCode = exception.HttpStatusCode;
        context.Response.ContentType = "application/json";

        var response = new
        {
            error = new
            {
                code = exception.ErrorCode,
                message = exception.Message,
                details = exception.Extensions.Count > 0 ? exception.Extensions : null
            }
        };

        return context.Response.WriteAsJsonAsync(response);
    }

    private Task HandleUnexpectedExceptionAsync(HttpContext context, Exception exception)
    {
        _logger.LogError(exception, "未处理异常: {Message}", exception.Message);

        context.Response.StatusCode = StatusCodes.Status500InternalServerError;
        context.Response.ContentType = "application/json";

        var response = new
        {
            error = new
            {
                code = "internal_server_error",
                message = exception.Message
                //stackTrace = _app.Environment.IsDevelopment() ? exception.StackTrace : null
            }
        };

        return context.Response.WriteAsJsonAsync(response);
    }
}